#ifndef _SIMULATION_H_
#define _SIMULATION_H_

#include <widgets.h>
#include "microbe.h"

struct Player
{
  bool alive;
  int food;
  Colour colour;
  AI* ai;
};

struct SimulationParameters
{
  Dimension screen_dim;
  unsigned num_players;
  Colour player_colour[SIM_MAX_PLAYERS];
  AI* ai[SIM_MAX_PLAYERS];
};

class Simulation: public ViewportRenderer
{
  public:
  Simulation(const SimulationParameters& parameters);
  ~Simulation();
  
  void update(unsigned dM, float dT);
  
  void onChangeDim(const Dimension& dim);
  void draw();
  
  private:
  void addFood(const Vector2& pos);
  void removeDeadFood();
  
  void addBullet(unsigned player_id, const Vector2& pos, float angle);
  void updateBullets(float dT);
  void removeDeadBullets();
  
  void addMicrobe(MicrobeType type, unsigned player_id, const Vector2& pos,
    float angle);
  void thinkMicrobes(int dM, float dT);
  void orderMicrobes(int dM, float dT);
  void orderSpeedyMicrobe(int i, int dM, float dT);
  void orderSoldierMicrobe(int i, int dM, float dT);
  void orderBigDaddyMicrobe(int i, int dM, float dT);
  void handleSoldierAttack(int i);
  void reproduceMicrobe(Microbe* microbe);
  void evolveMicrobe(Microbe* microbe);
  void collideMicrobes();
  void removeDeadMicrobes();
  
  void eatFood();
  void calcDone();
  
  void drawMicrobeSight(const Microbe* microbe);
  void drawMicrobe(const Microbe* microbe);
  void drawBullets();
  void drawStats();
  void drawGameInfo();
  
  bool _done;
  int _winner;
  
  Dimension _screen_dim;
  float _width;
  float _height;
  Rectf _bounds;
  
  unsigned _food_timer;
  unsigned _eat_timer;
  
  IdGen _food_id_gen;
  IdGen _microbe_id_gen;
  
  unsigned _num_players;
  Player _player[SIM_MAX_PLAYERS];
  unsigned _num_food;
  Food _food[SIM_MAX_FOOD];
  unsigned _num_bullets;
  Bullet _bullet[SIM_MAX_MICROBES];
  unsigned _num_microbes;
  Microbe _microbe[SIM_MAX_MICROBES];
  MicrobeOrder _order[SIM_MAX_MICROBES];
  
  unsigned _num_reproducing_microbes;
  Microbe* _reproducing_microbe[SIM_MAX_MICROBES];
  unsigned _num_evolving_microbes;
  Microbe* _evolving_microbe[SIM_MAX_MICROBES];
};

#endif
